package com.mtw.bbs.bbsUser.controller.admin;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mtw.bbs.bbsUser.constant.EUser;
import com.mtw.bbs.bbsUser.pojo.entity.User;
import com.mtw.bbs.bbsUser.pojo.form.PasswordForm;
import com.mtw.bbs.bbsUser.pojo.form.UserForm;
import com.mtw.bbs.bbsUser.pojo.vo.UserVo;
import com.mtw.bbs.bbsUser.service.*;
import com.mtw.bbs.common.core.exception.AuthException;
import com.mtw.bbs.common.core.exception.BusinessException;
import com.mtw.bbs.common.core.util.CommonUtil;
import com.mtw.bbs.common.core.vo.Result;
import com.mtw.bbs.fileAdmin.feign.FileClient;
import com.mtw.bbs.fileAdmin.pojo.vo.FileVo;
import com.mtw.bbs.userAdmin.pojo.vo.RoleVo;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户管理接口层
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("admin/user")
public class UserAdminController {

    private final FileClient fileClient;
    private final UserService userService;
    private final RoleService roleService;
    private final UserFollowService userFollowService;



    /**
     * 管理页查询非管理员用户
     */
    @GetMapping("/page")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页", paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "size", value = "分页大小", paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "name", value = "用户昵称", paramType = "query", dataType = "string")
    })
    @ApiOperation(value = "用户列表", notes = "")
    public Result<IPage<UserVo>> list(@RequestParam(name = "page") int page,
                                      @RequestParam(name = "size") int size,
                                      @RequestParam(name = "name",required = false) String name,
                                      @RequestParam(name = "code",required = false) String code) {

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.like(StringUtils.isNotBlank(name), User::getDisplayName, name);
        lqw.ne( User::getUserType, EUser.ADMIN);

        Page<User> userPage = userService.page(new Page<>(page, size), lqw);
        IPage<UserVo> dtoIPage = new Page<>();
        BeanUtils.copyProperties(userPage, dtoIPage);
        if (!CollectionUtils.isEmpty(userPage.getRecords())) {

            List<UserVo> collect = userPage.getRecords().stream().map(x -> {
                UserVo vo = new UserVo();
                BeanUtils.copyProperties(x, vo);
                vo.setFansCount(userFollowService.countOfFans(x.getId()));
                return vo;
            }).collect(Collectors.toList());
            setAvatarUrl(collect);
            dtoIPage.setRecords(collect);

        }
        return Result.success(dtoIPage);
    }


    /**
     * 选择界面查询非管理员用户
     */
    @GetMapping("/select")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页", paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "size", value = "分页大小", paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "name", value = "用户昵称", paramType = "query", dataType = "string")
    })
    @ApiOperation(value = "用户列表", notes = "")
    public Result<IPage<UserVo>> selectUser(@RequestParam(name = "page") int page,
                                      @RequestParam(name = "size") int size,
                                      @RequestParam(name = "name",required = false) String name) {

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.select(User::getId,User::getUsername,User::getDisplayName,User::getAvatar);
        lqw.like(StringUtils.isNotBlank(name), User::getDisplayName, name);
        lqw.ne( User::getUserType, EUser.ADMIN);

        Page<User> userPage = userService.page(new Page<>(page, size), lqw);
        IPage<UserVo> dtoIPage = new Page<>();
        BeanUtils.copyProperties(userPage, dtoIPage);
        if (!CollectionUtils.isEmpty(userPage.getRecords())) {

            List<UserVo> collect = userPage.getRecords().stream().map(x -> {
                UserVo vo = new UserVo();
                vo.setId(x.getId());
                vo.setUsername(x.getUsername());
                vo.setDisplayName(x.getDisplayName());
                vo.setAvatar(x.getAvatar());
                return vo;
            }).collect(Collectors.toList());
            setAvatarUrl(collect);
            dtoIPage.setRecords(collect);
        }
        return Result.success(dtoIPage);
    }


    /**
     * 管理页查询管理员用户
     */
    @GetMapping("/adminList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页", paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "size", value = "分页大小", paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "name", value = "用户昵称", paramType = "query", dataType = "string")
    })
    @ApiOperation(value = "管理员账号列表", notes = "")
    public Result<IPage<UserVo>> getAdminList(@RequestParam(name = "page") int page,
                                              @RequestParam(name = "size") int size,
                                              @RequestParam(name = "name",required = false) String name) {

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.like(StringUtils.isNotBlank(name), User::getDisplayName, name);
        lqw.eq(User::getUserType, EUser.ADMIN);

        Page<User> userPage = userService.page(new Page<>(page, size), lqw);
        IPage<UserVo> dtoIPage = new Page<>();
        BeanUtils.copyProperties(userPage, dtoIPage);
        if (!CollectionUtils.isEmpty(userPage.getRecords())) {

            Map<String, List<RoleVo>> userRoleMap = roleService.queryByUserIds(userPage.getRecords().stream().map(User::getId).toList());
            List<UserVo> collect = userPage.getRecords().stream().map(x -> {
                UserVo vo = new UserVo();
                BeanUtils.copyProperties(x, vo);
                vo.setRole(userRoleMap.get(x.getId()));
                return vo;
            }).collect(Collectors.toList());
            setAvatarUrl(collect);
            dtoIPage.setRecords(collect);
        }
        return Result.success(dtoIPage);
    }





    @PostMapping("/register")
    @ApiOperation(value = "注册普通用户", notes = "传入表单信息")
    public Result registerUser(@RequestBody UserForm form) {

        try {
            User user = new User();
            BeanUtils.copyProperties(form,user);
            userService.registerUser(user);
        }catch (BusinessException e){
            return Result.fail(e);
        }
        return Result.success();
    }


    @PostMapping("/registerAdmin")
    @ApiOperation(value = "注册管理员用户", notes = "传入表单信息")
    public Result registerAdmin(@RequestBody UserForm form) {

        try {
            userService.registerAdmin(form);
        }catch (BusinessException e){
            return Result.fail(e);
        }
        return Result.success();
    }



    @PutMapping("/updateAdmin")
    @ApiOperation(value = "更新管理用户", notes = "传入User表单")
    public Result updateAdmin(@RequestBody UserForm form) {

        try {
            userService.updateAdmin(form);
        }catch (BusinessException e){
            return Result.fail(e);
        }
        return Result.success();
    }



    @PutMapping("/update")
    @ApiOperation(value = "修改用户信息", notes = "传入User表单")
    public Result updateUser(@RequestBody UserForm form) {

        try {
            boolean updated = userService.updateUser(form);
            return updated?Result.success():Result.fail("修改失败");
        }catch (AuthException e){
            return Result.fail(e.getMessage());
        }
    }



    @PutMapping("/updatePassword/{id}")
    @ApiOperation(value = "修改密码", notes = "传入密码表单")
    public Result updatePassword(@PathVariable("id") String id,@RequestBody PasswordForm form) {

        LambdaUpdateWrapper<User> luw = new LambdaUpdateWrapper<>();
        luw.set(User::getPassword, CommonUtil.getMD5(form.getNewPassword()));
        luw.eq(User::getId, id);
        boolean update = userService.update(luw);
        return update?Result.success():Result.fail("修改失败");
    }



    @PutMapping("/disable/{id}")
    @ApiOperation("用户禁用")
    public Result ban(@PathVariable("id") String id) {

        List<String> list = new ArrayList<>(1);
        list.add(id);
        userService.updateUserStatus(list, 0);
        return Result.success();
    }


    @PutMapping("/enable/{id}")
    @ApiOperation("用户解除禁用")
    public Result openBan(@PathVariable("id") String id) {

        List<String> list = new ArrayList<>(1);
        list.add(id);
        userService.updateUserStatus(list, 1);
        return Result.success();
    }


    @PutMapping("/disableCommit/{id}")
    @ApiOperation("用户禁言")
    public Result disableCommit(@PathVariable("id") String id) {

        List<String> list = new ArrayList<>(1);
        list.add(id);
        userService.updateCommentStatus(list, 0);
        return Result.success();
    }


    @PutMapping("/enableCommit/{id}")
    @ApiOperation("用户解除禁言")
    public Result enableCommit(@PathVariable("id") String id) {

        List<String> list = new ArrayList<>(1);
        list.add(id);
        userService.updateCommentStatus(list, 1);
        return Result.success();
    }


    @DeleteMapping("/delete")
    @ApiOperation(value = "删除用户", notes = "传入id集合")
    public Result delete(@RequestBody String[] ids) {

        userService.removeBatchByIds(Arrays.asList(ids));
        return Result.success();
    }



    /**
     * 设置用户头像url
     */
    private void setAvatarUrl(List<UserVo> list){

        String[] fileIds = list.stream().map(UserVo::getAvatar).filter(StringUtils::isNotBlank).toArray(String[]::new);
        Result<List<FileVo>> fileUrls = fileClient.getFileUrlByIdArray(fileIds);
        Map<String, String> urlMap;
        if (fileUrls.isSuccess()){
            urlMap = fileUrls.getData().stream().collect(HashMap::new, (map, item) -> map.put(item.getId(), item.getUrl()), HashMap::putAll);
        }else {
            urlMap = new HashMap<>(1);
        }
        list.forEach(x->{
            if (urlMap.get(x.getAvatar()) != null){
                x.setAvatar(urlMap.get(x.getAvatar()));
            }
        });
    }



}
